###### Client in Machine order to UI Operator to control KT-Robot (JSON) 
###### Author: ZHENG
###### Date: 2023-11-27
###### START

import sys
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QSlider, QVBoxLayout
from PyQt5.QtCore import pyqtSlot, pyqtSignal 
from Ui_main import Ui_MainWindow
from PyQt5.QtGui import QIcon

from socket import *
import socket
import json

class MainWindow_main_zubo(QtWidgets.QMainWindow, Ui_MainWindow):

    def __init__(self):
        super(MainWindow_main_zubo, self).__init__()
        self.setupUi(self)
        self.initUI()
        self.initSingnal()   
        
    def initUI(self):        
        self.label_12.setText("通讯:(TCP)")
        self.label_10.setText("Server_IP")
        self.label_11.setText("Server_Port")
        self.btnConnect.setText("Connect")
        self.label_13.setText("Robot状态：")
        self.label_14.setText("运动控制：")        
        self.btn_Jog.setText("轴角坐标")
        self.btn_Coordinate.setText("世界坐标")
        self.label_17.setText("状态监控：")
        self.label_15.setText("API函数：")
        self.label_2.setText("速度")
        self.btnEmergence.setText("急停")
        self.btnHome.setText("机械复位")
        self.btnZero.setText("条件复位")
        self.btnStop.setText("停止")
        self.btnDO0.setText("DO0")
        self.btnDO1.setText("DO1")
        self.btnStatus.setText("状态获取")
        self.labelIO.setText("IO:")
        self.labelStatus.setText("状态")
        self.labelPose.setText("位姿")

        self.label_3.setText("轴J1 ： (度)")
        self.label_4.setText("轴J2 ： (度)")
        self.label_5.setText("轴J3 ： (度)")
        self.label_6.setText("轴J4 ： (度)")
        self.label_7.setText("轴J5 ： (度)")
        self.label_8.setText("轴J6 ： (度)")
        self.label_9.setText("轴J7 ： (度)")

        self.horizontalSlider_1.setRange(-101, 161)
        self.horizontalSlider_2.setRange(-40, 70)
        self.horizontalSlider_3.setRange(-170, 60)
        self.horizontalSlider_4.setRange(-350, 350)
        self.horizontalSlider_5.setRange(-205, 36)
        self.horizontalSlider_6.setRange(-360, 360)
        self.horizontalSlider_7.setRange(0,10)  

    def initSingnal(self):
        self.horizontalSlider_1.sliderReleased.connect(lambda: self.onSliderReleased(self.lineEdit_1))
        self.horizontalSlider_2.sliderReleased.connect(lambda: self.onSliderReleased(self.lineEdit_2))
        self.horizontalSlider_3.sliderReleased.connect(lambda: self.onSliderReleased(self.lineEdit_3))
        self.horizontalSlider_4.sliderReleased.connect(lambda: self.onSliderReleased(self.lineEdit_4))
        self.horizontalSlider_5.sliderReleased.connect(lambda: self.onSliderReleased(self.lineEdit_5))
        self.horizontalSlider_6.sliderReleased.connect(lambda: self.onSliderReleased(self.lineEdit_6))
        self.horizontalSlider_7.sliderReleased.connect(lambda: self.onSliderReleased(self.lineEdit_7))

        self.btnStatus.clicked.connect(self.onBtnStatus)
        self.btnConnect.clicked.connect(self.send_data_init)

    def onBtnStatus(self):
        print(f"How easy to get status")

    def onSliderReleased(self, Label):
        try:
            value = self.sender().value()
            Label.setText(str(value))
            QApplication.processEvents()
            self.updateValue2Lubancat()
        except ValueError:
            print(f"slider Value is Error: {value}")     

    def updateValue2Lubancat(self):
        server_IP = str(self.lineEdit_9.text())
        server_port = int(self.lineEdit_10.text())

        state = self.lineEdit_status.text()
        angles_0 = self.lineEdit_1.text()
        angles_1 = self.lineEdit_2.text()
        angles_2 = self.lineEdit_3.text()
        angles_3 = self.lineEdit_4.text()
        angles_4 = self.lineEdit_5.text()
        angles_5 = self.lineEdit_6.text()
        angles_6 = self.lineEdit_7.text()

        json_data_stytle = {  
            "cmd": "Robot_State",  
            "blockID": "123456789",  
            "deviceData": {  
                "name": "KT-LW-R6-1.0",  
                "type": "array",  
                "state": "Run",  
                "angle": [0, 0, 0, 0, 0, 0, 1],  
                "coordinate": [0, 0, 0, 0, 0, 0],  
                "pwm": [0, 0],  
                "mode": [0],  
                "dataReg": [0],  
                "robot_type": 1  
            },  
            "IO": {  
                "m_DI": [0, 0, 0],  
                "s1_DI": [0, 0, 0, 0, 0, 0, 0, 0],  
                "s1_stepP": [0, 0],  
                "s1_stepS": 0  
            }  
        }

        json_data_stytle["deviceData"]["state"] = state
        # json_data_stytle["deviceData"]["coordinate"]= 
        json_data_stytle["deviceData"]["angle"] = [angles_0, angles_1, angles_2, angles_3, angles_4, angles_5, angles_6]
        # json_data_stytle["deviceData"]["pwm"] = 
        # json_data_stytle["deviceData"]["mode"] = 

        json_str = json.dumps(json_data_stytle)
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        self.client_socket.connect((server_IP, server_port))

        self.client_socket.sendall(json_str.encode("gbk"))
        msg = self.client_socket.recv(1024).decode("gbk")
        data_json = json.loads(msg)
        self.receive_data_updateUI(data_json) 

    def receive_data_updateUI(self, msg):
        if msg == "ok":
            QApplication.processEvents()
        else:
            result_value = msg["deviceData"]["angle"]
            angle_x = result_value[0]
            angle_y = result_value[1]
            angle_z = result_value[2]
            angle_a = result_value[3]
            angle_b = result_value[4]
            angle_c = result_value[5]
            angle_d = result_value[6]
                        
            coordinate_value = msg["deviceData"]["coordinate"]
            cartesians_x = coordinate_value[0]
            cartesians_y = coordinate_value[1]
            cartesians_z = coordinate_value[2]
            cartesians_a = coordinate_value[3]
            cartesians_b = coordinate_value[4]
            cartesians_c = coordinate_value[5]

            pump_pwm = msg["deviceData"]["pwm"]
            motion_mode = msg["deviceData"]["mode"]
            state = msg["deviceData"]["state"]

            ### slider setValue
            self.horizontalSlider_1.setValue(int(float(angle_x)))
            self.horizontalSlider_2.setValue(int(float(angle_y)))
            self.horizontalSlider_3.setValue(int(float(angle_z)))
            self.horizontalSlider_4.setValue(int(float(angle_a)))
            self.horizontalSlider_5.setValue(int(float(angle_b)))
            self.horizontalSlider_6.setValue(int(float(angle_c)))
            self.horizontalSlider_7.setValue(int(float(angle_d)))

            self.lineEdit_1.setText(angle_x)
            self.lineEdit_2.setText(angle_y)
            self.lineEdit_3.setText(angle_z)
            self.lineEdit_4.setText(angle_a)
            self.lineEdit_5.setText(angle_b)
            self.lineEdit_6.setText(angle_c)
            self.lineEdit_7.setText(angle_d)
            self.lineEdit_status.setText(state)
            QApplication.processEvents()
         
    def send_data_init(self):
        server_IP = str(self.lineEdit_9.text())
        server_port = int(self.lineEdit_10.text())
 
        data = "?"
        self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        self.client_socket.connect((server_IP, server_port))
        self.client_socket.send(data.encode("gbk"))
        msg = self.client_socket.recv(1024).decode("gbk")
        data_json = json.loads(msg)
        self.receive_data_updateUI(data_json) 

    def validJog_Cartians_Speed(self, text):
        try:
            value = float(text)
            if value < -100 or value > 160:
                self.lineEdit.clear()
                print ("Value out of range")
        except ValueError:
            print()

if __name__== "__main__":
    app = QApplication(sys.argv)
    MainWindow = MainWindow_main_zubo()
    MainWindow.setWindowIcon(QIcon("./icon.jpg"))
    MainWindow.setWindowTitle("KT-Robot Demo")
    MainWindow.show()
    sys.exit(app.exec_())


###### Client in Machine order to UI Operator to control KT-Robot (JSON) 
###### Author: ZHENG
###### Date: 2023-12-7
###### ENF